﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Furion;
using Furion.DependencyInjection;
using PMP.Core.Entities;
using PMP.Core.Extensions;
using SqlSugar;

namespace PMP.Core.SqlSugar;

public class Repository<T> : SimpleClient<T> , ISingleton where T : BaseEntity, new() 
{
    public Repository()
    {
        base.Context = DbContext.Instance;
    }

    private int UserId => App.User.GetUserId();

    /// <summary>
    /// 添加/修改
    /// </summary>
    /// <param name="model"></param>
    /// <returns>主键</returns>
    public async Task<int> AddOrUpdateAsync(T model)
    {
        model.CreateUserId = UserId;
        model.UpdateUserId = UserId;
        model.CreateTime = DateTime.Now;
        model.UpdateTime = DateTime.Now;

        var res = model.Id;
        if (model.Id == 0)
        {
            res = await InsertReturnIdentityAsync(model);
        }
        else
        {
            // 更新时，忽略创建者和创建时间
            await Context.Updateable(model)
                .IgnoreColumns(a => new { CreateUserId = a.CreateUserId, a.CreateTime })
                .ExecuteCommandAsync();
        }
        return res;
    }
    /// <summary>
    /// 添加/修改
    /// </summary>
    /// <param name="list"></param>
    public async Task AddOrUpdateAsync(List<T> list)
    {
        var userId = UserId;
        list.ForEach(a =>
        {
            a.CreateUserId = userId;
            a.UpdateUserId = userId;
            a.CreateTime = DateTime.Now;
            a.UpdateTime = DateTime.Now;
        });
        var storage = await Context.Storageable(list).ToStorageAsync();

        await storage.AsInsertable.ExecuteCommandAsync();
        // 更新时，忽略创建者和创建时间
        await storage.AsUpdateable
            .IgnoreColumns(a => new { CreateUserId = a.CreateUserId, a.CreateTime })
            .ExecuteCommandAsync();
    }
    

    /// <summary>
    /// 获取分页列表
    /// </summary>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <param name="whereExpression"></param>
    /// <param name="orderByExpression"></param>
    /// <param name="isAsc"></param>
    /// <returns></returns>
    public async Task<Page<T>> GetPageAsync(int pageIndex, int pageSize, Expression<Func<T, bool>> whereExpression = null,
        Expression<Func<T, object>> orderByExpression = null, bool isAsc = false)
    {
        return await Context.Queryable<T>()
            .WhereIF(whereExpression != null, whereExpression)
            .OrderByIF(orderByExpression != null, orderByExpression, isAsc ? OrderByType.Asc : OrderByType.Desc)
            .OrderByIF(orderByExpression == null, a => a.UpdateTime, isAsc ? OrderByType.Asc : OrderByType.Desc)
            .ToPageAsync(pageIndex, pageSize);
    }
    /// <summary>
    /// 获取分页列表
    /// </summary>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <param name="whereExpression"></param>
    /// <param name="orderByExpression"></param>
    /// <param name="isAsc"></param>
    /// <returns></returns>
    public  Page<T> GetPage(int pageIndex, int pageSize, Expression<Func<T, bool>> whereExpression = null,
        Expression<Func<T, object>> orderByExpression = null, bool isAsc = false)
    {
        return  Context.Queryable<T>()
            .WhereIF(whereExpression != null, whereExpression)
            .OrderByIF(orderByExpression != null, orderByExpression, isAsc ? OrderByType.Asc : OrderByType.Desc)
            .OrderByIF(orderByExpression == null, a => a.UpdateTime, isAsc ? OrderByType.Asc : OrderByType.Desc)
            .ToPage(pageIndex, pageSize);
    }
}